<template>
  <div class="main">
    <div class="window-item" @click="sign(item)" v-for="item in doctors" :key="item.ID">
      <div class="item-text">{{item.Name}}</div>
      <div class="item-text return" v-if="IsReturnVisit(item)">回诊</div>
    </div>
  </div>
</template>

<script lang="ts">
import { Component } from 'vue-property-decorator'
import { mixins } from 'vue-class-component'
import { IDoctor } from '@/interface/common'
import ReservationMixin from '@/mixins/reservation'
import dayjs from 'dayjs'
import { IReservationPayAndRegisterQuery, IReturnVisitListData, IReturnVisitValidate } from './interface/reservation'
import { GetReturnVisitList, ReservationPayAndRegister, ReturnVisit } from './apis/reservation'

@Component
export default class Doctor extends mixins(ReservationMixin) {
  private doctors : IDoctor[] = []
  private async created () {
    this.showLoading()
    this.setTip('请选择医生')
    this.logger.info('打开医生选择页')
    this.setMaxTime(30)
    this.updateTimeHandler('home')
    if (this.store.state.client === undefined || this.store.state.client.Doctors === undefined || this.store.state.client.Doctors.length === 0) {
      this.hideLoading()
      this.$messageBox.show({ content: '很抱歉, 当前没有坐诊医生.' })
    }
    this.doctors = []
    this.returnVisitList = []
    this.store.state.client.Doctors.forEach(element => {
      if (this.checkDoctorTimeWorkInterval(element)) this.doctors.push(element)
    })
    this.getReturnVisitList()
    this.hideLoading()
  }

  private returnVisitList: IReturnVisitListData[] = []
  /**
   * 获取回诊列表
   */
  private async getReturnVisitList () {
    const cardNo = this.store.state.patient?.CardNo
    if (cardNo) {
      const response = await GetReturnVisitList({ CardNo: cardNo })
      if (response.data.Code === 200) {
        this.returnVisitList = response.data.Data
        this.logger.info(`获取回诊列表成功, 用户:${this.store.state.patient?.Name}, 回诊列表:${JSON.stringify(this.returnVisitList)}`)
      } else {
        this.logger.error(`获取回诊列表失败, 用户:${this.store.state.patient?.Name}, 返回信息:${response.data.Message}`)
      }
    }
  }

  private IsReturnVisit (doctor: IDoctor) {
    const index = this.returnVisitList.findIndex(e => e.EmpNumber === doctor.Code)
    return index > -1
  }

  /**
   * 回诊
   */
  private async returnVisit (doctor: IDoctor) {
    const visit = this.returnVisitList.find(e => e.EmpNumber === doctor.Code)
    if (!visit) {
      this.logger.error(`没有找到回诊信息, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
      this.$messageBox.show({
        content: '没有找到回诊信息, 请稍后重试!',
        duration: 5,
        confirmText: '关闭',
        confirm: () => {
          this.home()
        },
        showCancel: false
      })
      return
    }
    this.logger.info(`开始回诊挂号, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
    const data : IReturnVisitValidate = {
      id: visit.Id,
      cardNo: visit.CardNo,
      patientId: visit.PatientId,
      deptId: visit.DeptId,
      empNumber: visit.EmpNumber
    }
    const response = await ReturnVisit(data)
    if (response.data.Code === 200) {
      this.logger.info(`回诊挂号成功, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
      this.$messageBox.show({
        content: '回诊成功',
        duration: 3,
        confirmText: '关闭',
        confirm: () => {
          this.home()
        },
        showCancel: false
      })
      return
    }
    this.logger.info(`回诊挂号失败${response.data?.Message}, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
    this.$messageBox.show({
      content: `回诊失败${response.data?.Message}`,
      duration: 5,
      confirmText: '关闭',
      confirm: () => {
        this.home()
      },
      showCancel: false
    })
  }

  private addCredit (doctor: IDoctor) {
    const balance = this.store.state.patient?.Balance ?? 0
    let amount = parseFloat(doctor.TotalFee) - balance
    if (amount < 0) amount = 10
    this.store.state.AddCreditQuery = {
      Amount: parseFloat(this.ceil(amount, 2)),
      PatientId: this.store.state.patient?.ID ?? '',
      Use: '门诊充值'
    }
    this.$messageBox.show({
      content: '账户余额不足, 是否充值?',
      confirmText: '充值',
      confirm: () => {
        this.logger.info('用户确认充值')
        this.clearTimeout()
        this.navigateTo(`/${this.getRoute()}/register-pay`)
      },
      cancel: () => {
        this.logger.info('用户取消充值')
      }
    })
  }

  private ceil (number : number, fixed = 2) {
    if (!(fixed >= 0 && fixed <= 100)) {
      throw new RangeError('toCeil() digits argument must be between 0 and 100.')
    }
    let val = Math.ceil(number * Math.pow(10, fixed)) / Math.pow(10, fixed) + ''
    if (fixed > 0) {
      const intp = val.split('.')[0]
      const decp = val.split('.')[1] || ''
      if (decp.length < fixed) {
        val = intp + '.' + decp.padEnd(fixed, '0')
      }
    }
    return val
  }

  private busy = false
  /**
   * 挂号
   */
  private async sign (doctor: IDoctor) {
    if (this.busy) return
    this.busy = true
    if (this.IsReturnVisit(doctor)) {
      await this.returnVisit(doctor)
      return
    }
    this.showLoading('挂号中...')
    this.store.state.doctor = doctor
    this.logger.info(`开始挂号, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
    const depId = doctor.Room?.DepartmentId ?? ''
    const cardNo = this.store.state.patient?.CardNo ?? ''
    const query : IReservationPayAndRegisterQuery = {
      DeptId: depId,
      CardNo: cardNo,
      DoctorCode: doctor.Code
    }
    const result = await ReservationPayAndRegister(query)
    this.hideLoading()
    this.busy = false
    if (result.data?.Code === 200) {
      this.logger.info(`挂号成功, 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
      this.$messageBox.show({
        content: '挂号成功',
        duration: 3,
        confirmText: '关闭',
        confirm: () => {
          this.home()
        },
        showCancel: false
      })
    } else {
      if (result.data.Message.indexOf('余额不足') > -1) {
        this.logger.info(`挂号失败, 账户余额不足. 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
        this.addCredit(doctor)
        return
      }
      this.logger.info(`挂号失败, ${result.data?.Message}. 用户:${this.store.state.patient?.Name}, 医生:${doctor.Name}`)
      this.$messageBox.show({
        content: `挂号失败:${result.data?.Message}`,
        duration: 5,
        confirmText: '关闭',
        confirm: () => {
          this.home()
        },
        showCancel: false
      })
    }
  }

  /**
   * 判断医生是否坐诊
   */
  private checkDoctorTimeWorkInterval (doctor : IDoctor) : boolean {
    if (dayjs(doctor.Workday).format('YYYY-MM-DD') !== dayjs().format('YYYY-MM-DD')) return false
    for (let i = 0; i < doctor.WorkTimeIntervals.length; i++) {
      const element = doctor.WorkTimeIntervals[i]
      if (element.TimeInterval) {
        const start = dayjs(dayjs().format('YYYY-MM-DD') + ' ' + element.TimeInterval.StartTime).toDate()
        const end = dayjs(dayjs().format('YYYY-MM-DD') + ' ' + element.TimeInterval.EndTime).toDate()
        const now = new Date()
        if (now >= start && now <= end) {
          return true
        }
      }
    }
    return false
  }
}
</script>

<style scoped>
  .main {
    display: flex;
    justify-content: center;
    flex-wrap: wrap;
    height: 100%;
    align-items: center;
  }
  .window-item {
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    width: 30rem;
    height: 35rem;
    background-color: #388cc1;
    margin: 2rem;
    box-shadow: 0px 2px 10px 0px rgba(0, 0, 0, 0.05);
    border-radius: 5px;
    font-size: 5rem;
    position: relative;
    color: white;
  }
  .item-icon {
    font-size: 8rem;
  }
  .return{
    font-size: 4rem;
    color: yellow;
  }
</style>
